package com.chenfan.ccp.plug.log.config;

import com.chenfan.infra.constants.CommonBeanConstants;
import com.chenfan.ccp.common.listener.AbstractEventListener;
import com.chenfan.ccp.plug.log.annotation.RecordBody;
import com.chenfan.ccp.plug.log.util.TenantIdUtil;
import com.chenfan.ccp.plug.rpc.util.RpcResourceUtil;
import com.chenfan.ccp.util.start.ApplicationContextUtil;
import com.chenfan.ccp.utils.TraceIdUtil;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import net.logstash.logback.encoder.org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

public class FeignInterceptorConfig extends AbstractEventListener implements RequestInterceptor {
    private static final Logger logger = LoggerFactory.getLogger("RPC_LOG");

    public FeignInterceptorConfig() {
    }

    @Override
    public void apply(RequestTemplate requestTemplate) {
        setHeader(requestTemplate, TraceIdUtil.SHORT_TRACE_ID, TraceIdUtil.getMDC(TraceIdUtil.SHORT_TRACE_ID));
        setHeader(requestTemplate, CommonBeanConstants.TENANT_ID, TraceIdUtil.getMDC(CommonBeanConstants.TENANT_ID));
        setHeader(requestTemplate, CommonBeanConstants.USER_ID, TraceIdUtil.getMDC(CommonBeanConstants.USER_ID));
        setHeader(requestTemplate,"projectName", ApplicationContextUtil.getServiceName());
        setHeader(requestTemplate, "feign", "true");

        //是否打印参数
        //排除文件上传类型参会
        //排除RecordBody
        List<String> formParams = requestTemplate.methodMetadata().formParams();
        boolean uploadFile = !formParams.isEmpty() && formParams.contains("file");
        Optional<RecordBody> recordBody = Arrays.stream(requestTemplate.methodMetadata().method().getAnnotations())
                .filter(annotation -> annotation instanceof RecordBody).map(RecordBody.class::cast).findFirst();
        boolean logParam = !recordBody.isPresent() || recordBody.get().logParam();
        if (!uploadFile || logParam) {
            logger.info("开始请求服务={},requestTemplate={}", Optional.ofNullable(requestTemplate.feignTarget()).get().name(), requestTemplate);
        } else {
            logger.info("开始请求服务={},path={}", Optional.ofNullable(requestTemplate.feignTarget()).get().name(), requestTemplate.path());
        }


        // 拿到当前租户ID, 设置到上下文中
        String tenantId = TenantIdUtil.getTenantId();
        if (!StringUtils.isEmpty(tenantId)) {
            requestTemplate.header(CommonBeanConstants.TENANT_ID, tenantId);
        }

        //send event
//        sendEvent(CollectEventListener.builder().
//                traceId(TraceIdUtil.getTraceId()).
//                data(requestTemplate.body() + "")
//                .type(BusinessLogTypeEnums.RPC).build());

        RpcResourceUtil.close();
    }

    @Override
    public Object getListener() {
        return this;
    }

    private void setHeader(RequestTemplate requestTemplate,String key,String value){
        if(Objects.nonNull(value)) {
            requestTemplate.header(key, value);
        }
    }
}
